package container

import "sync"

// 创建一个队列类型
type SyncQueue[q any] struct {
	//队列长度
	len int
	//队列头
	head *SyncQueueNode[q]
	//队列尾
	tail *SyncQueueNode[q]
	//读写锁
	rw sync.RWMutex
}

// 创建一个队列node
type SyncQueueNode[q any] struct {
	//当前节点的值
	value q
	//下一个节点
	next *SyncQueueNode[q]
	//上一个节点
	prev *SyncQueueNode[q]
}

// 创建一个队列
func NewSyncSyncQueue[q any]() *SyncQueue[q] {
	return &SyncQueue[q]{
		rw: sync.RWMutex{},
	}
}

// 创建一个队列node
func NewSyncQueueNode[q any](value q) *SyncQueueNode[q] {
	return &SyncQueueNode[q]{value: value}
}

// 获取队列长度
func (q *SyncQueue[Q]) Len() int {
	q.rw.RLock()
	defer q.rw.RUnlock()
	return q.len
}

// 获取队列头
func (q *SyncQueue[Q]) Head() *SyncQueueNode[Q] {
	q.rw.RLock()
	defer q.rw.RUnlock()
	return q.head
}

// 获取队列尾
func (q *SyncQueue[Q]) Tail() *SyncQueueNode[Q] {
	q.rw.RLock()
	defer q.rw.RUnlock()
	return q.tail
}

// 获取队列头的值
func (q *SyncQueue[Q]) HeadValue() Q {
	q.rw.RLock()
	defer q.rw.RUnlock()
	return q.head.value
}

// 获取队列尾的值
func (q *SyncQueue[Q]) TailValue() Q {
	q.rw.RLock()
	defer q.rw.RUnlock()
	return q.tail.value
}

// 弹出队列头
func (q *SyncQueue[Q]) PopHead() Q {
	q.rw.Lock()
	defer q.rw.Unlock()
	if q.head == nil {
		var a Q
		return a
	}
	value := q.head.value
	q.head = q.head.next
	q.len--
	// 判断长度是否为0, 如果为0则尾部也为nil
	if q.len == 0 {
		q.tail = nil
	}

	return value
}

// 弹出队列尾
func (q *SyncQueue[Q]) PopTail() Q {
	q.rw.Lock()
	defer q.rw.Unlock()
	if q.tail == nil {
		var a Q
		return a
	}
	value := q.tail.value
	q.tail = q.tail.prev
	q.len--
	// 判断长度是否为0, 如果为0则头部也为nil
	if q.len == 0 {
		q.head = nil
	}
	return value
}

// 添加队列头
func (q *SyncQueue[Q]) PushHead(value Q) {
	q.rw.Lock()
	defer q.rw.Unlock()
	node := NewSyncQueueNode[Q](value)
	if q.head == nil {
		q.head = node
		q.tail = node
	} else {
		node.next = q.head
		q.head.prev = node
		q.head = node
	}
	q.len++
}

// 添加队列尾
func (q *SyncQueue[Q]) PushTail(value Q) {
	q.rw.Lock()
	defer q.rw.Unlock()
	node := NewSyncQueueNode[Q](value)
	if q.tail == nil {
		q.head = node
		q.tail = node
	} else {
		node.prev = q.tail
		q.tail.next = node
		q.tail = node
	}
	q.len++
}

// 遍历队列
func (q *SyncQueue[Q]) Range(f func(index int, value Q) bool) {
	q.rw.RLock()
	defer q.rw.RUnlock()
	for i, node := 0, q.head; node != nil; i, node = i+1, node.next {
		if !f(i, node.value) {
			break
		}
	}
}

// 获取队列所有值
func (q *SyncQueue[Q]) Values() []Q {
	q.rw.RLock()
	defer q.rw.RUnlock()
	var values []Q
	for i, node := 0, q.head; node != nil; i, node = i+1, node.next {
		values = append(values, node.value)
	}
	return values
}
